/******************************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Ltd.                       */
/*                                                                            */
/*  NAME      = frdb_cursor.c                                                 */
/*  NOTE      = Cursor共通处理                                                */
/*  DATE      = 2014/12/17 by zhengxd                                         */
/******************************************************************************/
#include <stdio.h>
#include <string.h>
#include <ctype.h>

#include "frdb_cursor.h"

#define FRDB_1000000_MSEC      1000000
#define FRDB_PARAM_SIZE        48
#define FRDB_ROWS_SIZE         36

/*******************************************************************************
*  FUNC     :  取得时间差(微秒)
*  ARGS     :  st_start_time(开始时间)
*           :  p_st_end_time(结束时间)
*  RTN      :  long
*  NOTE     :  todo提共通
*******************************************************************************/
FR_STATIC unsigned long __frdb_get_interval_time(struct timeval *p_st_start_time
                                               , struct timeval *p_st_end_time)
{
    unsigned long ul_time_interval = 0;
    int i_flg = 0;

    if (p_st_start_time->tv_usec < p_st_end_time->tv_usec)
    {
        ul_time_interval = p_st_end_time->tv_usec - p_st_start_time->tv_usec;
    }
    else
    {
        ul_time_interval = 1000000 + p_st_end_time->tv_usec - p_st_start_time->tv_usec;
        i_flg = 1;
    }

    if (p_st_start_time->tv_sec + i_flg > p_st_end_time->tv_sec)
    {
        ul_time_interval = 0;
    }
    else
    {
        ul_time_interval += 1000000 * (p_st_end_time->tv_sec - p_st_start_time->tv_sec - i_flg);
    }

    return ul_time_interval;
}

/*******************************************************************************
*  FUNC     :  内存释放(Frdata_field **)
*  ARGS     :  pp_st_data(Frdata_field **)
*  RTN      :  void
*  NOTE     :  todo提共通
*******************************************************************************/
FR_STATIC void __frdb_frdata_free(Frdata_field **pp_st_data)
{
    if (pp_st_data == NULL || *pp_st_data == NULL)
    {
        return;
    }

    Frdata_field *p_st_data = *pp_st_data;
    if (p_st_data->p_field_name)
    {
        frfree(p_st_data->p_field_name);
    }
    if (p_st_data->p_field_value)
    {
        frfree(p_st_data->p_field_value);
    }
    frfree(p_st_data);
    *pp_st_data = NULL;
    return;
}

/*******************************************************************************
*  FUNC     :  List节点释放(Frdata_field *)
*  ARGS     :  p_st_node(Frdata_field节点)
*  RTN      :  void
*  NOTE     :  todo提共通
*******************************************************************************/
FR_STATIC void __frdb_frdata_node_free(Frlist_node *p_st_node)
{
    if (p_st_node == NULL || p_st_node->data == NULL)
    {
        return;
    }

    Frdata_field *p_st_data = (Frdata_field *)p_st_node->data;
    if (p_st_data->p_field_name)
    {
        frfree(p_st_data->p_field_name);
    }
    if (p_st_data->p_field_value)
    {
        frfree(p_st_data->p_field_value);
    }
    frfree(p_st_data);
    return;
}

int frdb_title_value_chg(char *p_org_title
                         , char c_chg_word
                         , char **pp_result_title)
{
    if (p_org_title == NULL
        || *p_org_title == '\0'
        || pp_result_title == NULL)
    {
        return FR_FAIL;
    }

    int i_index = 0;
    int i_count = 0;
    int i_first = FR_YES;
    unsigned int ui_loop = 0;
    unsigned int ui_org_len = strlen(p_org_title);
    char *p_tmp = NULL;
    char *p_result_title = NULL;
    char *p_result_tmp = NULL;

    p_result_title = (char *)frmalloc(ui_org_len + 1);
    if (p_result_title == NULL)
    {
        return FR_FAIL;
    }
    p_result_tmp = p_result_title;

    while (*p_org_title)
    {
        switch (*p_org_title)
        {
            case ',':
            case '(':
                p_result_tmp[ui_loop++] = *p_org_title;
                p_org_title++;
                /* 拷贝空白字符 */
                while (*p_org_title == ' '
                        || *p_org_title == '\t'
                        || *p_org_title == '\r'
                        || *p_org_title == '\n')
                {
                    if (i_first == FR_YES)
                    {
                        i_first = FR_NO;
                        p_result_tmp[ui_loop++] = *p_org_title;
                    }
                    p_org_title++;
                }
                i_first = FR_YES;
                /* 将可能是数值的替换成要替换的字符 */
                /*
                * 情形1: values(null,100,null)
                * 情形2: values(null,100 ,null)
                * 情形3: values(null,100)
                * 情形4: values(null,100 )
                * 情形5: values(100)
                * 情形6: values(100 )
                */
                if (*p_org_title >= '0' && *p_org_title <= '9')
                {
                    /* 查询第一个出现[空白字符][,][)]的位置 */
                    i_index = strcspn(p_org_title + 1, " \t\r\n,)");
                    if (i_index < 0)
                    {
                        p_result_tmp[ui_loop++] = *p_org_title;
                        p_org_title++;
                        break;
                    }
                    /* 确认index长字符串是否全是数值 */
                    else
                    {
                        /* 查询第一个出现不是数值的位置 */
                        i_count = strspn(p_org_title + 1, "0123456789.");
                        if (i_count < 0 || i_count < i_index)
                        {
                            p_result_tmp[ui_loop++] = *p_org_title;
                            p_org_title++;
                            break;
                        }
                        else
                        {
                            p_result_tmp[ui_loop++] = c_chg_word;
                            p_org_title += i_index + 1;
                        }
                    }
                }
                else if (*p_org_title == '\'')/* 替换''之间的 */
                {
                    break;
                }
                else if (*p_org_title != '\0')
                {
                    p_result_tmp[ui_loop++] = toupper(*p_org_title);
                    p_org_title++;
                }
                break;

            case '=':
                p_result_tmp[ui_loop++] = *p_org_title;
                p_org_title++;
                /* 拷贝空白字符 */
                while (*p_org_title == ' '
                        || *p_org_title == '\t'
                        || *p_org_title == '\r'
                        || *p_org_title == '\n')
                {
                    if (i_first == FR_YES)
                    {
                        i_first = FR_NO;
                        p_result_tmp[ui_loop++] = *p_org_title;
                    }
                    p_org_title++;
                }
                i_first = FR_YES;
                /* 将可能是数值的替换成要替换的字符 */
                /*
                * 情形1: values = 1000 and
                * 情形2: values = 1000 where
                * 情形3: values = 1000
                */
                if (*p_org_title >= '0' && *p_org_title <= '9')
                {
                    /* 查询第一个出现[空白字符]的位置 */
                    i_index = strcspn(p_org_title + 1, " \t\r\n,)");
                    if (i_index < 0)
                    {
                        /* 确认是否以数值结尾 */
                        i_count = strspn(p_org_title + 1, "0123456789.");
                        if (i_count < 0)
                        {
                            p_result_tmp[ui_loop++] = c_chg_word;
                            p_result_tmp[ui_loop] = '\0';
                            *pp_result_title = p_result_title;
                            return FR_SUCC;
                        }
                        p_result_tmp[ui_loop++] = *p_org_title;
                        p_org_title++;
                        break;
                    }
                    /* 确认index长字符串是否全是数值 */
                    else
                    {
                        /* 查询第一个出现不是数值的位置 */
                        i_count = strspn(p_org_title + 1, "0123456789.");
                        if (i_count < 0 || i_count < i_index)
                        {
                            p_result_tmp[ui_loop++] = *p_org_title;
                            p_org_title++;
                            break;
                        }
                        else
                        {
                            p_result_tmp[ui_loop++] = c_chg_word;
                            p_org_title += i_index + 1;
                        }
                    }
                }
                else if (*p_org_title == '\'')/* 替换''之间的 */
                {
                    break;
                }
                else if (*p_org_title != '\0')
                {
                    p_result_tmp[ui_loop++] = toupper(*p_org_title);
                    p_org_title++;
                }
                break;

            case '\'':
                /* 查找下一个['] */
                p_tmp = strchr(p_org_title + 1, '\'');
                while (p_tmp)
                {
                    /* 忽略[\']  */
                    if (*(p_tmp - 1) == '\\')
                    {
                        p_tmp = strchr(p_tmp + 1, '\'');
                    }
                    else
                    {
                        break;
                    }
                }
                /* 替换引号里的值 */
                if (p_tmp)
                {
                    p_result_tmp[ui_loop++] = c_chg_word;
                    p_org_title = p_tmp + 1;
                }
                /*没有匹配的[']，实际情况应该不会有,将之后的都当做一个值  */
                else
                {
                    p_result_tmp[ui_loop++] = c_chg_word;
                    p_result_tmp[ui_loop] = '\0';
                    *pp_result_title = p_result_title;
                    return FR_SUCC;
                }
                break;

            default:
               while (*p_org_title == ' '
                        || *p_org_title == '\t'
                        || *p_org_title == '\r'
                        || *p_org_title == '\n')
                {
                    if (i_first == FR_YES)
                    {
                        i_first = FR_NO;
                        p_result_tmp[ui_loop++] = *p_org_title;
                    }
                    p_org_title++;
                }
                if (i_first == FR_NO)
                {
                    i_first = FR_YES;
                    break;
                }
                if (*p_org_title == '\0')
                {
                    break;
                }
               p_result_tmp[ui_loop++] = toupper(*p_org_title);
               p_org_title++;
               break;
        }
    }

    p_result_tmp[ui_loop] = '\0';
    *pp_result_title = p_result_title;
    return FR_SUCC;
}

void frdb_metadata_free(Sql_metadata_info **pp_st_metadata)
{
    if (pp_st_metadata == NULL || *pp_st_metadata == NULL)
    {
        return;
    }

    frfree(*pp_st_metadata);
    *pp_st_metadata = NULL;

    return;
}

void frdb_metadata_node_free(Frlist_node *p_st_node)
{
    if (p_st_node == NULL || p_st_node->data == NULL)
    {
        return;
    }

    frfree(p_st_node->data);
    return;
}

int frdb_add_metadata_info(Sql_statement *p_st_statement
                          , int i_type
                          , Sql_metadata_info *p_st_metadata)
{
    if (p_st_statement == NULL || p_st_metadata == NULL)
    {
       return FR_FAIL;
    }

    Frlist_node *p_st_node = NULL;

    /* 创建node */
    p_st_node = frlist_node_create(p_st_metadata);
    if (p_st_node == NULL)
    {
        return FR_FAIL;
    }

    /* 追加节点 */
    if (i_type == FRDB_BIND)
    {
        frlist_push(&(p_st_statement->st_metadata_bind), p_st_node);
    }
    else if (i_type == FRDB_COLUMN)
    {
        frlist_push(&(p_st_statement->st_metadata_column), p_st_node);
    }
    else
    {
        frlist_push(&(p_st_statement->st_metadata_define), p_st_node);
    }

    return FR_SUCC;
}

Frlist_node* frdb_get_first_metadata(Sql_statement *p_st_statement
                                    , int i_type)
{
    if (p_st_statement == NULL)
    {
        return NULL;
    }
    Frlist_node *p_st_node = NULL;

    /* 追加节点 */
    if (i_type == FRDB_BIND)
    {
        p_st_node = FRLIST_FIRST_NODE(&(p_st_statement->st_metadata_bind));
    }
    else if (i_type == FRDB_COLUMN)
    {
        p_st_node = FRLIST_FIRST_NODE(&(p_st_statement->st_metadata_column));
    }
    else
    {
        p_st_node = FRLIST_FIRST_NODE(&(p_st_statement->st_metadata_define));
    }

    return p_st_node;
}

Sql_metadata_info* frdb_get_specified_metadata(Sql_statement *p_st_statement
                                               , int i_type, int i_index)
{
    if (p_st_statement == NULL)
    {
        return NULL;
    }
    Frlist_node *p_st_node = NULL;
    Sql_metadata_info *p_st_metadata = NULL;

    /* 取得指定节点 */
    if (i_type == FRDB_BIND)
    {
        p_st_node = frlist_node_idx(&(p_st_statement->st_metadata_bind), i_index);
    }
    else if (i_type == FRDB_COLUMN)
    {
        p_st_node = frlist_node_idx(&(p_st_statement->st_metadata_column), i_index);
    }
    else
    {
        p_st_node = frlist_node_idx(&(p_st_statement->st_metadata_define), i_index);
    }

    p_st_metadata = (Sql_metadata_info *) FRLIST_GET_NODE_DATA(p_st_node);
    return p_st_metadata;
}

void frdb_field_bind_free(Sql_field_bind **pp_st_data)
{
    if (pp_st_data == NULL || *pp_st_data == NULL)
    {
        return;
    }

    Sql_field_bind *p_st_data = *pp_st_data;
    frlist_remove_all(&(p_st_data->st_field_list), __frdb_frdata_node_free);
    frfree(p_st_data);
    *pp_st_data = NULL;
    return;
}

void frdb_field_bind_node_free(Frlist_node *p_st_node)
{
    if (p_st_node == NULL || p_st_node->data == NULL)
    {
        return;
    }

    Sql_field_bind *p_st_data = (Sql_field_bind *)p_st_node->data;
    frlist_remove_all(&(p_st_data->st_field_list), __frdb_frdata_node_free);
    frfree(p_st_data);
    return;
}

int frdb_frlist_copy(Frlist_header *p_lst_source, Frlist_header *p_lst_dest)
{
    char *p_field_value = NULL;
    char *p_field_name = NULL;
    unsigned int ui_index = frlist_size(p_lst_dest);
    Frlist_node *p_st_node_new = NULL;
    Frdata_field *p_st_data_new = NULL;
    Frlist_node *p_st_node_source = NULL;
    Frdata_field *p_st_data_source = NULL;

    /* 取得头结点 */
    p_st_node_source = FRLIST_FIRST_NODE(p_lst_source);
    /* 遍历list */
    while (p_st_node_source)
    {
        /* 取得源data */
        p_st_data_source = (Frdata_field *)FRLIST_GET_NODE_DATA(p_st_node_source);
        /* 创建新data */
        p_st_data_new = (Frdata_field *)frmalloc(sizeof(Frdata_field));
        if (p_st_data_new == NULL)
        {
            frlist_remove_all(p_lst_dest, __frdb_frdata_node_free);
            return FR_FAIL;
        }
        memset(p_st_data_new, 0x0, sizeof(Frdata_field));

        /* 拷贝filed name */
        if (p_st_data_source->p_field_name)
        {
            p_field_name = frstrdup(p_st_data_source->p_field_name);
            if (p_field_name == NULL)
            {
                __frdb_frdata_free(&p_st_data_new);
                frlist_remove_all(p_lst_dest, __frdb_frdata_node_free);
                return FR_FAIL;
            }
            p_st_data_new->p_field_name = p_field_name;
        }

        /* 拷贝filed value */
        if (p_st_data_source->p_field_value)
        {
            p_field_value = frstrdup(p_st_data_source->p_field_value);
            if (p_field_value == NULL)
            {
                __frdb_frdata_free(&p_st_data_new);
                frlist_remove_all(p_lst_dest, __frdb_frdata_node_free);
                return FR_FAIL;
            }
            p_st_data_new->p_field_value = p_field_value;
        }

        /* 设置数据类型 */
        p_st_data_new->em_data_type = p_st_data_source->em_data_type;
        p_st_data_new->i_field_index = ++ui_index;

        /* 创建节点 */
        p_st_node_new = frlist_node_create(p_st_data_new);
        if (p_st_node_new == NULL)
        {
            __frdb_frdata_free(&p_st_data_new);
            frlist_remove_all(p_lst_dest, __frdb_frdata_node_free);
            return FR_FAIL;
        }
        /* 追加节点 */
        frlist_push(p_lst_dest, p_st_node_new);
        /* 取得下一个节点 */
        p_st_node_source = FRLIST_NEXT_NODE(p_st_node_source);
    }

    return FR_SUCC;
}

void frdb_resultset_free(Sql_resultset **pp_st_resultset)
{
    if (pp_st_resultset == NULL || *pp_st_resultset == NULL)
    {
        return;
    }

    Sql_resultset *p_st_resultset = *pp_st_resultset;
    /* 释放bind list */
    frlist_remove_all(&(p_st_resultset->st_bind_list), frdb_field_bind_node_free);
    /* 释放响应行数 */
    if (p_st_resultset->p_ul_rows)
    {
        frfree(p_st_resultset->p_ul_rows);
    }

    frfree(p_st_resultset);
    *pp_st_resultset = NULL;
    return;
}

void frdb_resultset_node_free(Frlist_node *p_st_node)
{
    if (p_st_node == NULL || p_st_node->data == NULL)
    {
        return;
    }

    Sql_resultset *p_st_resultset = (Sql_resultset *)p_st_node->data;
    /* 释放bind value */
    frlist_remove_all(&(p_st_resultset->st_bind_list), frdb_field_bind_node_free);
    /* 释放响应行数 */
    if (p_st_resultset->p_ul_rows)
    {
        frfree(p_st_resultset->p_ul_rows);
    }

    frfree(p_st_resultset);
    return;
}

void frdb_statement_free(Sql_statement **pp_st_statement)
{
    if (pp_st_statement == NULL || *pp_st_statement == NULL)
    {
        return;
    }

    Sql_statement *p_st_statement = *pp_st_statement;
    /* 释放数据 */
    if (p_st_statement->p_sql)
    {
        frfree(p_st_statement->p_sql);
    }
    /* 释放metadata */
    frlist_remove_all(&(p_st_statement->st_metadata_bind)
                     , frdb_metadata_node_free);
    frlist_remove_all(&(p_st_statement->st_metadata_column)
                     , frdb_metadata_node_free);
    frlist_remove_all(&(p_st_statement->st_metadata_define)
                     , frdb_metadata_node_free);
    /* 释放结果集 */
    frlist_remove_all(&(p_st_statement->st_resultset_list)
                      , frdb_resultset_node_free);

    frfree(p_st_statement);
    *pp_st_statement = NULL;
    return;
}

void frdb_statement_node_free(Frlist_node *p_st_node)
{
    if (p_st_node == NULL || p_st_node->data == NULL)
    {
        return;
    }

    Sql_statement *p_st_statement = (Sql_statement *)p_st_node->data;
    /* 释放数据 */
    if (p_st_statement->p_sql)
    {
        frfree(p_st_statement->p_sql);
    }
    /* 释放metadata */
    frlist_remove_all(&(p_st_statement->st_metadata_bind)
                     , frdb_metadata_node_free);
    frlist_remove_all(&(p_st_statement->st_metadata_column)
                     , frdb_metadata_node_free);
    frlist_remove_all(&(p_st_statement->st_metadata_define)
                     , frdb_metadata_node_free);

    /* 释放结果集 */
    frlist_remove_all(&(p_st_statement->st_resultset_list)
                     , frdb_resultset_node_free);

    frfree(p_st_statement);
    return;
}

Sql_statement* frdb_create_statement()
{
    Sql_statement *p_st_statement = NULL;

    /* 创建结构体 */
    p_st_statement = (Sql_statement *)frmalloc(sizeof(Sql_statement));
    if (p_st_statement == NULL)
    {
        return NULL;
    }
    memset(p_st_statement, 0x0, sizeof(Sql_statement));
    p_st_statement->i_is_first = 1;

    return p_st_statement;
}

int frdb_is_first_result(Sql_statement *p_st_statement)
{
    return p_st_statement->i_is_first;
}

void frdb_statement_used(Sql_statement *p_st_statement)
{
    p_st_statement->i_is_first = 0;
    return;
}

void frdb_set_sql(Sql_statement *p_st_statement, char *p_sql)
{
    p_st_statement->p_sql = p_sql;
    return;
}

void frdb_reset_sql(Sql_statement *p_st_statement, char *p_sql)
{
    if (p_st_statement->p_sql)
    {
        frfree(p_st_statement->p_sql);
    }
    p_st_statement->p_sql = p_sql;
    return;
}

Sql_resultset* frdb_create_resultset(unsigned long ul_req_sequence)
{
    Sql_resultset *p_st_resultset = NULL;

    /* 创建resultset */
    p_st_resultset = (Sql_resultset *)frmalloc(sizeof(Sql_resultset));
    if (p_st_resultset == NULL)
    {
        return NULL;
    }
    memset(p_st_resultset, 0x0, sizeof(Sql_resultset));
    p_st_resultset->ul_req_sequence = ul_req_sequence;
    p_st_resultset->i_req_report = FR_NO;

    /* 结果出力 */
    return p_st_resultset;
}

int frdb_add_resultset_bind(Sql_resultset *p_st_resultset
                            , Sql_field_bind *p_st_bind)
{
    if (p_st_resultset == NULL || p_st_bind == NULL)
    {
        return FR_FAIL;
    }
    Frlist_node *p_st_node = NULL;

    /* 创建节点 */
    p_st_node = frlist_node_create(p_st_bind);
    if (p_st_node == NULL)
    {
        return FR_FAIL;
    }

    /* 追加节点 */
    frlist_push(&(p_st_resultset->st_bind_list), p_st_node);
    return FR_SUCC;
}

int frdb_add_resultset(Sql_statement *p_st_statement
                      , Sql_resultset *p_st_resultset)
{
    if (p_st_statement == NULL || p_st_resultset == NULL)
    {
        return FR_FAIL;
    }
    Frlist_node *p_st_node = NULL;

    /* 创建节点 */
    p_st_node = frlist_node_create(p_st_resultset);
    if (p_st_node == NULL)
    {
        return FR_FAIL;
    }

    /* 追加节点 */
    frlist_push(&(p_st_statement->st_resultset_list), p_st_node);
    return FR_SUCC;
}

void frdb_init_resultset(Sql_resultset *p_st_resultset
                        , unsigned long ul_req_sequence)
{
    if (p_st_resultset == NULL)
    {
        return;
    }

    /* 释放bind list */
    frlist_remove_all(&(p_st_resultset->st_bind_list), frdb_field_bind_node_free);
    /* 释放响应行数 */
    if (p_st_resultset->p_ul_rows)
    {
        frfree(p_st_resultset->p_ul_rows);
    }
    memset(p_st_resultset, 0x0, sizeof(Sql_resultset));
    p_st_resultset->i_req_report = FR_NO;
    p_st_resultset->ul_req_sequence = ul_req_sequence;

    return;
}

Sql_resultset* frdb_get_last_resultset(Sql_statement *p_st_statement)
{
    if (p_st_statement == NULL)
    {
        return NULL;
    }
    unsigned int ui_list_size = 0;
    Frlist_node *p_st_node = NULL;
    Sql_resultset *p_st_resultset = NULL;

    /* 取得list的格式，即最后一个node的index */
    ui_list_size = frlist_size(&(p_st_statement->st_resultset_list));
    p_st_node = frlist_node_idx(&(p_st_statement->st_resultset_list), ui_list_size - 1);
    if (p_st_node == NULL || p_st_node->data == NULL)
    {
        return NULL;
    }

    p_st_resultset = (Sql_resultset *)p_st_node->data;
    return p_st_resultset;
}

void frdb_del_first_resultset(Sql_statement *p_st_statement)
{
    if (p_st_statement == NULL)
    {
        return;
    }
    Frlist_node *p_st_node = NULL;
    Frlist_header *p_lst_header = &(p_st_statement->st_resultset_list);

    p_st_node = frlist_remove_head(p_lst_header);
    /* 释放节点 */
    if (p_st_node)
    {
        frdb_resultset_node_free(p_st_node);
        frfree(p_st_node);
    }
    return;
}

void frdb_del_last_resultset(Sql_statement *p_st_statement)
{
    if (p_st_statement == NULL)
    {
        return;
    }
    Frlist_node *p_st_node_pre = NULL;
    Frlist_node *p_st_node_curr = NULL;
    Frlist_header *p_lst_header = &(p_st_statement->st_resultset_list);

    p_st_node_curr = FRLIST_FIRST_NODE(p_lst_header);
    while (p_st_node_curr)
    {
        if (FRLIST_NEXT_NODE(p_st_node_curr))
        {
            p_st_node_pre = p_st_node_curr;
        }
        else //释放最后一个节点
        {
            if (p_st_node_pre == NULL)
            {
                frlist_remove_head(p_lst_header);
            }
            else
            {
                p_lst_header->size -= 1;
                p_lst_header->tail = p_st_node_pre;
                p_st_node_pre->next = NULL;
            }
            /* 释放节点 */
            frdb_resultset_node_free(p_st_node_curr);
            frfree(p_st_node_curr);
        }
        p_st_node_curr = FRLIST_NEXT_NODE(p_st_node_curr);
    }

    return;
}

Sql_resultset* frdb_get_specified_resultset(Sql_statement *p_st_statement
                                           , long l_sequence_id)
{
    if (p_st_statement == NULL)
    {
        return NULL;
    }
    Frlist_node *p_st_node = NULL;
    Sql_resultset *p_st_resultset = NULL;

    /* 取得头结点 */
    p_st_node = FRLIST_FIRST_NODE(&(p_st_statement->st_resultset_list));
    /* 遍历list */
    while (p_st_node)
    {
        /* 取得源data */
        p_st_resultset = (Sql_resultset *)FRLIST_GET_NODE_DATA(p_st_node);
        if (p_st_resultset->l_id == l_sequence_id)
        {
            return p_st_resultset;
        }
        /* 取得下一个节点 */
        p_st_node = FRLIST_NEXT_NODE(p_st_node);
    }

    return NULL;
}

void frdb_del_specified_resultset(Sql_statement *p_st_statement
                                 , long l_sequence_id)
{
    if (p_st_statement == NULL)
    {
        return;
    }
    Frlist_node *p_st_node_del = NULL;
    Frlist_node *p_st_node_pre = NULL;
    Frlist_node *p_st_node_curr = NULL;
    Sql_resultset *p_st_resultset = NULL;
    Frlist_header *p_lst_header = &(p_st_statement->st_resultset_list);

    p_st_node_curr = FRLIST_FIRST_NODE(p_lst_header);
    /* 遍历list */
    while (p_st_node_curr)
    {
        p_st_resultset = (Sql_resultset *)FRLIST_GET_NODE_DATA(p_st_node_curr);
        /* 删除本节点 */
        if (p_st_resultset->l_id == l_sequence_id)
        {
            /* 该node是最后一个节点,需要设置tail */
            if (p_st_node_curr->next == NULL)
            {
                p_lst_header->tail = p_st_node_pre;
            }

            /* 要删除的节点是头结点 */
            if (p_st_node_pre == NULL)
            {
                p_st_node_del = frlist_remove_head(p_lst_header);
                break;
            }
            else
            {
                p_lst_header->size -= 1;
                p_st_node_pre->next = p_st_node_curr->next;
                p_st_node_del = p_st_node_curr;
                break;
            }
        }

        /* 取得下一个node */
        p_st_node_pre = p_st_node_curr;
        p_st_node_curr = FRLIST_NEXT_NODE(p_st_node_curr);
    }

    /* 释放节点 */
    if (p_st_node_del)
    {
        frdb_resultset_node_free(p_st_node_del);
        frfree(p_st_node_del);
    }

    return;
}

int frdb_set_resultset_req2(Sql_resultset *p_st_resultset
                            , unsigned long ul_request_bytes
                            , struct timeval *p_st_request_start_time
                            , struct timeval *p_st_request_end_time)
{
    if (p_st_resultset == NULL)
    {
        return FR_FAIL;
    }
    /* 设置请求数据第一个分片包发送的时间 */
    p_st_resultset->st_req_resp.st_request_start_time.tv_sec
                                              = p_st_request_start_time->tv_sec;
    p_st_resultset->st_req_resp.st_request_start_time.tv_usec
                                             = p_st_request_start_time->tv_usec;
    /* 设置所有请求数据发送完的时间 */
    p_st_resultset->st_req_resp.st_request_end_time.tv_sec
                                                = p_st_request_end_time->tv_sec;
    p_st_resultset->st_req_resp.st_request_end_time.tv_usec
                                               = p_st_request_end_time->tv_usec;
    /* 设置客户端时间 */
    p_st_resultset->st_req_resp.ul_send_time_us = __frdb_get_interval_time(
                                                       p_st_request_start_time
                                                       , p_st_request_end_time);
    /* 设置请求字节数，in bytes */
    p_st_resultset->st_req_resp.ul_request_bytes += ul_request_bytes;
    return FR_SUCC;
}

int frdb_set_resultset_resp2(Sql_resultset *p_st_resultset
                            , unsigned long ul_response_bytes
                            , unsigned int ui_response_count
                            , unsigned long *p_ul_effect_rows
                            , struct timeval *p_st_response_start_time
                            , struct timeval *p_st_response_end_time)
{
    if (p_st_resultset == NULL ||
        (p_st_resultset->st_req_resp.st_request_end_time.tv_sec == 0 &&
         p_st_resultset->st_req_resp.st_request_end_time.tv_usec == 0))
    {
        return FR_FAIL;
    }
    unsigned int i_loop = 0;

    /* 设置应答数据第一个分片包发送的时间 */
    p_st_resultset->st_req_resp.st_response_start_time.tv_sec
                                              = p_st_response_start_time->tv_sec;
    p_st_resultset->st_req_resp.st_response_start_time.tv_usec
                                             = p_st_response_start_time->tv_usec;
    /* 设置所有应答数据发送完的时间 */
    p_st_resultset->st_req_resp.st_response_end_time.tv_sec
                                                = p_st_response_end_time->tv_sec;
    p_st_resultset->st_req_resp.st_response_end_time.tv_usec
                                               = p_st_response_end_time->tv_usec;
    /* 设置服务端时间 */
    p_st_resultset->st_req_resp.ul_server_time_us += __frdb_get_interval_time(
                                &p_st_resultset->st_req_resp.st_request_end_time
                                , p_st_response_start_time);
    /* 设置服务端时间 */
    p_st_resultset->st_req_resp.ul_download_time_us += __frdb_get_interval_time(
                                                      p_st_response_start_time
                                                      , p_st_response_end_time);
    /* 设置应答字节数，in bytes */
    p_st_resultset->st_req_resp.ul_response_bytes += ul_response_bytes;

    /* 设置影响行数传进来，不用设置影响行数 */
    if (p_ul_effect_rows != NULL && ui_response_count)
    {
        /* 创建响应行数信息 */
        if (p_st_resultset->p_ul_rows == NULL)
        {
            p_st_resultset->p_ul_rows = (unsigned long *)frmalloc(ui_response_count * sizeof(unsigned long));
            if (p_st_resultset->p_ul_rows == NULL)
            {
                return FR_FAIL;
            }
            memset(p_st_resultset->p_ul_rows, 0x0, ui_response_count * sizeof(unsigned long));
            p_st_resultset->ui_response_count = ui_response_count;
            while (i_loop < ui_response_count)
            {
                p_st_resultset->p_ul_rows[i_loop] = p_ul_effect_rows[i_loop];
                i_loop++;
            }
        }
        /* 设置已有响应信息行数 */
        else
        {
            if (p_st_resultset->ui_response_count == ui_response_count)
            {
                while (i_loop < ui_response_count)
                {
                    p_st_resultset->p_ul_rows[i_loop] += p_ul_effect_rows[i_loop];
                    i_loop++;
                }
            }
            /* 前后响应不一致，实际情况应不会发生 */
            else
            {
                frdbg("Current response code is different than before\n");
                return FR_FAIL;
            }
        }
    }

    return FR_SUCC;
}

int frdb_set_resultset_req(Sql_statement *p_st_statement
                          , int i_flg
                          , long l_sequence_id
                          , unsigned long ul_request_bytes
                          , struct timeval *p_st_request_start_time
                          , struct timeval *p_st_request_end_time)
{
    int i_ret = FR_SUCC;
    Sql_resultset *p_st_resultset = NULL;

    /* 取得要跟新的节点 */
    if (i_flg == FRDB_LAST)
    {
        p_st_resultset = frdb_get_last_resultset(p_st_statement);
    }
    else
    {
        p_st_resultset = frdb_get_specified_resultset(p_st_statement, l_sequence_id);
    }
    /* 更新request信息 */
    i_ret = frdb_set_resultset_req2(p_st_resultset, ul_request_bytes
                                   , p_st_request_start_time
                                   , p_st_request_end_time);
    return i_ret;
}

int frdb_set_resultset_resp(Sql_statement *p_st_statement
                           , int i_flg
                           , long l_sequence_id
                           , unsigned long ul_response_bytes
                           , unsigned int ui_response_count
                           , unsigned long *p_ul_effect_rows
                           , struct timeval *p_st_response_start_time
                           , struct timeval *p_st_response_end_time)
{
    int i_ret = FR_SUCC;
    Sql_resultset *p_st_resultset = NULL;

    /* 取得要跟新的节点 */
    if (i_flg == FRDB_LAST)
    {
        p_st_resultset = frdb_get_last_resultset(p_st_statement);
    }
    else
    {
        p_st_resultset = frdb_get_specified_resultset(p_st_statement
                                                     , l_sequence_id);
    }
    /* 更新response信息 */
    i_ret = frdb_set_resultset_resp2(p_st_resultset
                                    , ul_response_bytes
                                    , ui_response_count
                                    , p_ul_effect_rows
                                    , p_st_response_start_time
                                    , p_st_response_end_time);
    return i_ret;
}

FR_STATIC int __frdb_create_req(Sql_statement *p_st_statement
                              , Sql_resultset *p_st_resultset
                              , Frreport_body_data **pp_st_body_session)
{
    int i_ret = FR_SUCC;
    int i_batch_index = 1;
    int i_param_index = 1;
    unsigned int ui_len_tmp = 0;
    unsigned int ui_batch_count = 0;
    unsigned int ui_param_count = 0;
    Frlist_node *p_st_node_source = NULL;
    Frdata_field *p_st_data_source = NULL;
    Frlist_node *p_field_bind_node = NULL;
    Sql_field_bind *p_st_field_bind = NULL;
    Frreport_body_data *p_st_body_req = *pp_st_body_session;
    unsigned long ul_req_sequence = frdb_get_req_sequence2(p_st_resultset);
    Sql_req_resp_info st_req_resp = p_st_resultset->st_req_resp;
    char *p_sql = p_st_statement->p_sql;
    char arr_param[FRDB_PARAM_SIZE] = {0};
    strncpy(arr_param, FRDB_REPORT_KEY_REQ_SQL_BATCH, FRDB_PARAM_SIZE);
    char *p_value = NULL;
    char *p_param = arr_param;
    char *p_param_tmp = arr_param;
    char *p_title = NULL;
    /* 17 is length of request.sql.batch */
    p_param += 17;

    /* add transtaion title */
    i_ret = frdb_title_value_chg(p_sql, FRDB_CHG_WORD, &p_title);
    if (i_ret != FR_SUCC)
    {
        return FR_FAIL;
    }
    i_ret = frreport_body_l7_add_str(p_st_body_req
                                    , APM_REPORT_KEY_TRANS_TITLE
                                    , p_title ? p_title : "");
    frfree(p_title);
    if (i_ret != FR_SUCC)
    {
        return FR_FAIL;
    }

    /* add sequence id */
    i_ret = frreport_body_l7_add_ulong(p_st_body_req
                                      , APM_REPORT_KEY_REQ_ID, ul_req_sequence);
    if (i_ret != FR_SUCC)
    {
        return FR_FAIL;
    }
    /* add isResponseRequired */
    i_ret = frreport_body_l7_add_int(p_st_body_req
                                    , APM_REPORT_KEY_REQ_ISRESPREQUIRED, 1);
    if (i_ret != FR_SUCC)
    {
        return FR_FAIL;
    }
    /* add request start time */
    i_ret = frreport_body_l7_add_timeval(p_st_body_req
                                        , APM_REPORT_KEY_REQ_START_TIMESTAMP
                                        , &st_req_resp.st_request_start_time);
    if (i_ret != FR_SUCC)
    {
        return FR_FAIL;
    }
    /* add request end time */
    i_ret = frreport_body_l7_add_timeval(p_st_body_req
                                        , APM_REPORT_KEY_REQ_END_TIMESTAMP
                                        , &st_req_resp.st_request_end_time);
    if (i_ret != FR_SUCC)
    {
        return FR_FAIL;
    }
    /* add sql statement */
    i_ret = frreport_body_l7_add_str(p_st_body_req, FRDB_REPORT_KEY_REQ_TEXT
                                    , p_sql ? p_sql : "");
    if (i_ret != FR_SUCC)
    {
        return FR_FAIL;
    }
    /* add send time */
    i_ret = frreport_body_l7_add_ulong(p_st_body_req
                                      , APM_REPORT_KEY_REQ_SEND_TIME_US
                                      , st_req_resp.ul_send_time_us);
    if (i_ret != FR_SUCC)
    {
        return FR_FAIL;
    }
    /* add send data bytes */
    i_ret = frreport_body_l7_add_ulong(p_st_body_req
                                      , APM_REPORT_KEY_REQ_DATA_BYTES
                                      , st_req_resp.ul_request_bytes);
    if (i_ret != FR_SUCC)
    {
        return FR_FAIL;
    }

    /* get batch count */
    ui_batch_count = frlist_size(&p_st_resultset->st_bind_list);
    if (ui_batch_count == 0)
    {
        ui_batch_count = 1;
    }
    /* add request batch count */
    i_ret = frreport_body_l7_add_int(p_st_body_req
                                    , FRDB_REPORT_KEY_REQ_SQL_BATCH_SIZE
                                    , ui_batch_count);
    if (i_ret != FR_SUCC)
    {
        return FR_FAIL;
    }

    /* 取得参数列表 */
    p_field_bind_node = FRLIST_FIRST_NODE(&p_st_resultset->st_bind_list);
    while (p_field_bind_node)
    {
        memset(p_param, 0x0, FRDB_PARAM_SIZE - 17);
        snprintf(p_param, FRDB_PARAM_SIZE - 17, ".%d.param.", i_batch_index++);
        ui_len_tmp = strlen(arr_param);
        p_param_tmp = arr_param;
        p_param_tmp += ui_len_tmp;
        i_param_index = 1;

        p_st_field_bind = (Sql_field_bind *)FRLIST_GET_NODE_DATA(p_field_bind_node);
        if (p_st_field_bind)
        {
            /* get param count */
            ui_param_count = frlist_size(&(p_st_field_bind->st_field_list));
            if (ui_param_count)
            {
                snprintf(p_param_tmp, FRDB_PARAM_SIZE - ui_len_tmp, "size");
                /* add request batch count */
                i_ret = frreport_body_l7_add_int(p_st_body_req, arr_param, ui_param_count);
                if (i_ret != FR_SUCC)
                {
                    return FR_FAIL;
                }
            }
            memset(p_param_tmp, 0x0, FRDB_PARAM_SIZE - ui_len_tmp);
            p_st_node_source = FRLIST_FIRST_NODE(&(p_st_field_bind->st_field_list));
            while (p_st_node_source)
            {
                /* 取得源data */
                p_st_data_source = (Frdata_field *)FRLIST_GET_NODE_DATA(p_st_node_source);
                snprintf(p_param_tmp, FRDB_PARAM_SIZE - ui_len_tmp, "%d", i_param_index++);
                if(p_st_data_source)
                    p_value = p_st_data_source->p_field_value;
                else
                    p_value = NULL;
                i_ret = frreport_body_l7_add_str(p_st_body_req
                                                , arr_param
                                                , p_value ? p_value : "");
                if (i_ret != FR_SUCC)
                {
                    return FR_FAIL;
                }
                /* 取得下一个节点 */
                p_st_node_source = FRLIST_NEXT_NODE(p_st_node_source);
            }
        }
        /* 取得下一个field bind */
        p_field_bind_node = FRLIST_NEXT_NODE(p_field_bind_node);
    }

    return FR_SUCC;
}

int frdb_report_req2(Conntrack *p_st_conn
                    , Frhash_header *p_st_hash_report
                    , Sql_statement *p_st_statement
                    , Sql_resultset *p_st_resultset
                    , Frreport_body_data **pp_st_body_session)
{
    /* statement和result必须不为NULL */
    if (p_st_statement == NULL || p_st_resultset == NULL)
    {
        return FR_FAIL;
    }
    int i_ret = FR_SUCC;
    Frreport_data *p_st_report_data = NULL;
    Frreport_body_data *p_st_body_req = *pp_st_body_session;

    i_ret = __frdb_create_req(p_st_statement, p_st_resultset, pp_st_body_session);
    if (i_ret != FR_SUCC)
    {
        return FR_FAIL;
    }

    /* 创建report data header */
    p_st_report_data = frreport_data_l7_new(FRREPORT_TYPE_L7DATA_REQ);
    if (p_st_report_data == NULL)
    {
        return FR_FAIL;
    }
    /* add body into header */
    i_ret = frreport_data_add_body(p_st_report_data, p_st_body_req);
    if (i_ret != FR_SUCC)
    {
        frreport_data_free(&p_st_report_data);
        return FR_FAIL;
    }
    *pp_st_body_session = NULL;

    /* 上报request数据 */
    i_ret = frreport_data_hash(p_st_hash_report, p_st_report_data);
    if (i_ret != FR_SUCC)
    {
        frreport_data_free(&p_st_report_data);
        return FR_FAIL;
    }

    p_st_resultset->i_req_report = FR_YES;
    return FR_SUCC;
}

int frdb_report_resp2(Conntrack *p_st_conn
                     , Frhash_header *p_st_hash_report
                     , Sql_statement *p_st_statement
                     , Sql_resultset *p_st_resultset
                     , long l_resp_code
                     , char *p_error_code
                     , char *p_error_msg
                     , Frreport_body_data **pp_st_body_session)
{
    /* statement和result必须不为NULL */
    if (p_st_statement == NULL || p_st_resultset == NULL)
    {
        return FR_FAIL;
    }
    int i_ret = FR_SUCC;
    unsigned int i_batch_index = 0;
    Frlist_header *p_st_sess = NULL;
    Frreport_data *p_st_report_data = NULL;
    Frreport_body_data *p_st_body_resp = NULL;
    unsigned long *p_ul_effect_rows = p_st_resultset->p_ul_rows;
    unsigned int ui_response_count = p_st_resultset->ui_response_count;
    Sql_req_resp_info st_req_resp = p_st_resultset->st_req_resp;
    char arr_rows[FRDB_ROWS_SIZE] = {0};
    strncpy(arr_rows, FRDB_REPORT_KEY_RESP_SQL_BATCH, FRDB_ROWS_SIZE);
    char *p_rows = arr_rows;
    /* 18 is length of response.sql.batch */
    p_rows += 18;

    if (p_st_resultset->i_req_report == FR_NO)
    {
        /* 先复制session信息 */
        p_st_sess = FRREPORT_BODY_L7LIST_CLONE_COMM(*pp_st_body_session);
        if (p_st_sess == NULL)
        {
            return FR_FAIL;
        }
        /* 上报request并且取得request report data */
        i_ret = frdb_report_req2(p_st_conn, p_st_hash_report
                                , p_st_statement, p_st_resultset
                                , pp_st_body_session);
        if (i_ret != FR_SUCC)
        {
            frreport_body_l7list_free(&p_st_sess);
            return i_ret;
        }
        /* 由于session已经在request被上报，所以需要重新创建 */
        p_st_body_resp = frreport_body_new_l7(p_st_conn);
        if (p_st_body_resp == NULL)
        {
            frreport_body_l7list_free(&p_st_sess);
            return FR_FAIL;
        }
        /* 设置session信息 */
        i_ret = FRREPORT_BODY_L7LIST_SET_COMM(p_st_body_resp, &p_st_sess);
        if (i_ret != FR_SUCC)
        {
            frreport_body_l7list_free(&p_st_sess);
            return i_ret;
        }
    }
    else
    {
        p_st_body_resp = *pp_st_body_session;
        *pp_st_body_session = NULL;
    }

    i_ret = __frdb_create_req(p_st_statement, p_st_resultset, &p_st_body_resp);
    if (i_ret != FR_SUCC)
    {
        return FR_FAIL;
    }

    /* add response code */
    i_ret = frreport_body_l7_add_long(p_st_body_resp
                                     , APM_REPORT_KEY_RESP_CODE
                                     , l_resp_code);
    if (i_ret != FR_SUCC)
    {
        frreport_body_free(&p_st_body_resp);
        return FR_FAIL;
    }
    /* add response code string */
    i_ret = frreport_body_l7_add_str(p_st_body_resp
                                     , APM_REPORT_KEY_RESP_CODE_STRING
                                     , p_error_code ? p_error_code : "");
    if (i_ret != FR_SUCC)
    {
        frreport_body_free(&p_st_body_resp);
        return FR_FAIL;
    }
    /* add response error message */
    i_ret = frreport_body_l7_add_str(p_st_body_resp, APM_REPORT_KEY_RESP_ERR_MSG
                                    , p_error_msg ? p_error_msg : "");
    if (i_ret != FR_SUCC)
    {
        frreport_body_free(&p_st_body_resp);
        return FR_FAIL;
    }
    /* add response start time */
    i_ret = frreport_body_l7_add_timeval(p_st_body_resp
                                        , APM_REPORT_KEY_RESP_START_TIMESTAMP
                                        , &st_req_resp.st_response_start_time);
    if (i_ret != FR_SUCC)
    {
        frreport_body_free(&p_st_body_resp);
        return FR_FAIL;
    }
    /* add response end time */
    i_ret = frreport_body_l7_add_timeval(p_st_body_resp
                                        , APM_REPORT_KEY_RESP_END_TIMESTAMP
                                        , &st_req_resp.st_response_end_time);
    if (i_ret != FR_SUCC)
    {
        frreport_body_free(&p_st_body_resp);
        return FR_FAIL;
    }
    /* add response response_time_us */
    i_ret = frreport_body_l7_add_ulong(p_st_body_resp
                                      , APM_REPORT_KEY_RESP_SERVER_TIME_US
                                      , st_req_resp.ul_server_time_us);
    if (i_ret != FR_SUCC)
    {
        frreport_body_free(&p_st_body_resp);
        return FR_FAIL;
    }
    /* add response response_time_us */
    i_ret = frreport_body_l7_add_ulong(p_st_body_resp
                                      , APM_REPORT_KEY_RESP_DOWNLOAD_TIME_US
                                      , st_req_resp.ul_download_time_us);
    if (i_ret != FR_SUCC)
    {
        frreport_body_free(&p_st_body_resp);
        return FR_FAIL;
    }
    /* add response firstbyte time us */
    i_ret = frreport_body_l7_add_ulong(p_st_body_resp
                                      , APM_REPORT_KEY_RESP_DATA_BYTES
                                      , st_req_resp.ul_response_bytes);
    if (i_ret != FR_SUCC)
    {
        frreport_body_free(&p_st_body_resp);
        return FR_FAIL;
    }

    /* 设置response rows */
    while (i_batch_index < ui_response_count)
    {
        snprintf(p_rows, FRDB_ROWS_SIZE - 18, ".%d.rows", i_batch_index + 1);
        i_ret = frreport_body_l7_add_ulong(p_st_body_resp, arr_rows
                                          , p_ul_effect_rows[i_batch_index++]);
        if (i_ret != FR_SUCC)
        {
            frreport_body_free(&p_st_body_resp);
            return FR_FAIL;
        }
    }

    /* 创建report data header */
    p_st_report_data = frreport_data_l7_new(FRREPORT_TYPE_L7DATA_RESP);
    if (p_st_report_data == NULL)
    {
        frreport_body_free(&p_st_body_resp);
        return FR_FAIL;
    }
    /* add body into header */
    i_ret = frreport_data_add_body(p_st_report_data, p_st_body_resp);
    if (i_ret != FR_SUCC)
    {
        frreport_data_free(&p_st_report_data);
        frreport_body_free(&p_st_body_resp);
        return FR_FAIL;
    }
    /* 上报reponse数据 */
    i_ret = frreport_data_hash(p_st_hash_report, p_st_report_data);
    if (i_ret != FR_SUCC)
    {
        frreport_data_free(&p_st_report_data);
        return FR_FAIL;
    }
    return FR_SUCC;
}

int frdb_report_req(Conntrack *p_st_conn
                   , Frhash_header *p_st_hash_report
                   , Sql_statement *p_st_statement
                   , int i_flg
                   , long l_sequence_id
                   , Frreport_body_data **pp_st_body_session)
{
    if (p_st_statement == NULL)
    {
        return FR_FAIL;
    }

    int i_ret = FR_SUCC;
    Sql_resultset *p_st_resultset = NULL;

    /* 取得结果集 */
    if (i_flg == FRDB_LAST)
    {
        p_st_resultset = frdb_get_last_resultset(p_st_statement);
    }
    else
    {
        p_st_resultset = frdb_get_specified_resultset(p_st_statement
                                                     , l_sequence_id);
    }

    /* 上报request数据 */
    i_ret = frdb_report_req2(p_st_conn, p_st_hash_report, p_st_statement
                            , p_st_resultset, pp_st_body_session);
    return i_ret;
}

int frdb_report_resp(Conntrack *p_st_conn
                    , Frhash_header *p_st_hash_report
                    , Sql_statement *p_st_statement
                    , int i_flg
                    , long l_sequence_id
                    , long l_resp_code
                    , char *p_error_code
                    , char *p_error_msg
                    , Frreport_body_data **pp_st_body_session)
{
    if (p_st_statement == NULL)
    {
        return FR_FAIL;
    }

    int i_ret = FR_SUCC;
    Sql_resultset *p_st_resultset = NULL;

    /* 取得结果集 */
    if (i_flg == FRDB_LAST)
    {
        p_st_resultset = frdb_get_last_resultset(p_st_statement);
    }
    else
    {
        p_st_resultset = frdb_get_specified_resultset(p_st_statement
                                                     , l_sequence_id);
    }
    /* 上报resposne */
    i_ret = frdb_report_resp2(p_st_conn, p_st_hash_report, p_st_statement
                             , p_st_resultset, l_resp_code, p_error_code
                             , p_error_msg, pp_st_body_session);
    return i_ret;
}

int frdb_add_statement(Frhash_header *p_hash_header
                      , long l_cursor_id
                      , Sql_statement *p_st_statement)
{
    if (p_st_statement == NULL)
    {
        return FR_FAIL;
    }
    Frlist_node *p_st_node = NULL;

    frhash2_delLong(p_hash_header, l_cursor_id, frdb_statement_node_free);

    /* 设置cursor ID */
    p_st_statement->l_cursor_id = l_cursor_id;
    /* 创建hash节点 */
    p_st_node = frlist_node_create(p_st_statement);
    if (p_st_node == NULL)
    {
        return FR_FAIL;
    }

    frhash2_addLong(p_hash_header, l_cursor_id, p_st_node);

    return FR_SUCC;
}


Sql_statement* frdb_get_statement(Frhash_header *p_hash_header
                                  , long l_cursor_id)
{
    Frlist_node *p_st_node = NULL;
    Sql_statement *p_st_statement = NULL;

    /* 到hash表中找到对应的prepare语句 */
    p_st_node = frhash2_getLong(p_hash_header, l_cursor_id);

    p_st_statement = (Sql_statement *) FRLIST_GET_NODE_DATA(p_st_node);
    return p_st_statement;
}

int frdb_set_req_sequence(Sql_statement *p_st_statement
                          , int i_flg
                          , long l_sequence_id
                          , unsigned long ul_req_sequence)
{
    Sql_resultset *p_st_resultset = NULL;

    /* 取得结果集 */
    if (i_flg == FRDB_LAST)
    {
        p_st_resultset = frdb_get_last_resultset(p_st_statement);
    }
    else
    {
        p_st_resultset = frdb_get_specified_resultset(p_st_statement
                                                     , l_sequence_id);
    }

    /* 没有对应的resultset */
    if (p_st_resultset == NULL)
    {
        return FR_FAIL;
    }

    p_st_resultset->ul_req_sequence = ul_req_sequence;
    return FR_SUCC;
}


void frdb_set_req_sequence2(Sql_resultset *p_st_resultset
                            , unsigned long ul_req_sequence)
{
    p_st_resultset->ul_req_sequence = ul_req_sequence;
    return;
}


unsigned long frdb_get_req_sequence(Sql_statement *p_st_statement
                          , int i_flg
                          , long l_sequence_id)
{
    Sql_resultset *p_st_resultset = NULL;

    /* 取得结果集 */
    if (i_flg == FRDB_LAST)
    {
        p_st_resultset = frdb_get_last_resultset(p_st_statement);
    }
    else
    {
        p_st_resultset = frdb_get_specified_resultset(p_st_statement
                                                     , l_sequence_id);
    }

    /* 没有对应的resultset */
    if (p_st_resultset == NULL)
    {
        return 0;
    }

    return p_st_resultset->ul_req_sequence;
}


unsigned long frdb_get_req_sequence2(Sql_resultset *p_st_resultset)
{
    return p_st_resultset->ul_req_sequence;
}


void frdb_set_column_nums(Sql_statement *p_st_statement, int i_column_nums)
{
    p_st_statement->i_column_nums = i_column_nums;
    return;
}


int frdb_get_column_nums(Sql_statement *p_st_statement)
{
    return p_st_statement->i_column_nums;
}
